import Core.Config as Config
import os
import datetime
import Core.WindFunctions as Wind
import DataProcess
import Core.Gadget as Gadget
import re


# 下载合约信息
def Download_Future_Contract_Info(symbol_list):
    # ---Request Fields---
    fields = ["sec_name", "ipo_date", "exch_eng"]
    fields.append("lasttrade_date")  # ---最后交易日
    fields.append("lastdelivery_date")  # ---最后交割日
    fields.append("dlmonth")  # 交割月份
    fields.append("lprice")  # 挂牌基准价
    fields.append("sccode")  # 交易品种
    fields.append("margin")  # 交易保证金
    fields.append("punit")  # 报价单位
    fields.append("changelt")  # 涨跌幅限制
    fields.append("mfprice")  # 最小变动价位
    fields.append("contractmultiplier")  # 合约乘数

    data = None
    if len(symbol_list) != 0:
        data = Wind.WSS(symbol_list, fields)

    #
    documants = []
    if data != None:
        #
        for iSymbol in range(len(symbol_list)):
            symbol = symbol_list[iSymbol]

            if symbol == "AF1808-S.CFE":
                kkwood = 0
            # find a valid maturity date
            # element = Gadget.FindElement(instrumentsInDatabase, {"Symbol": symbol})
            # if element == None:
            #    print("Symbol Not Existed " + symbol)
            #    continue

            # ---Parse Instrument Code---
            a = symbol.split(".")
            # pattern = "^([a-zA-Z]{1,5})([0-9]{3,4}).([a-zA-Z]{1,10})"
            pattern = "^([a-zA-Z]{1,5})([0-9]{3,4})([-S]*)"
            b = re.match(pattern, a[0])
            # print(text[b.regs[1][0]:b.regs[1][1]])
            # print(text[b.regs[2][0]:b.regs[2][1]])
            # print(text[b.regs[3][0]:b.regs[3][1]])

            # ---Build Object---
            dataObject = {}
            dataObject["Symbol"] = symbol
            dataObject["Description"] = data[iSymbol]["sec_name"]
            dataObject["Exchange"] = data[iSymbol]["exch_eng"]
            dataObject["Term"] = data[iSymbol]["dlmonth"]
            dataObject["Raw_Code"] = symbol[b.regs[1][0]:b.regs[1][1]]
            # dataObject["ExchangeCode"] = symbol[b.regs[3][0]:b.regs[3][1]]
            dataObject["Exchange_Code"] = a[1]
            dataObject["Begin_Price"] = data[iSymbol]["lprice"]
            dataObject["Underly"] = data[iSymbol]["sccode"]
            dataObject["Margin"] = data[iSymbol]["margin"]
            dataObject["Quotation"] = data[iSymbol]["punit"]
            dataObject["Change_Limit"] = data[iSymbol]["changelt"]
            dataObject["Minimum_Move"] = data[iSymbol]["mfprice"]
            dataObject["Unit"] = data[iSymbol]["contractmultiplier"]
            #
            datetime1 = Gadget.FilterWindDateTimeDirty(data[iSymbol]["ipo_date"])
            datetime2 = Gadget.FilterWindDateTimeDirty(data[iSymbol]["lasttrade_date"])
            lastDeliveryDateTime = Gadget.FilterWindDateTimeDirty(data[iSymbol]["lastdelivery_date"])
            # dataObject["DateTime1"] = Gadget.ToUTCDateTime(datetime1)
            # dataObject["DateTime2"] = Gadget.ToUTCDateTime(datetime2)
            # dataObject["LastDeliveryDate"] = Gadget.ToUTCDateTime(lastDeliveryDateTime)
            dataObject["DateTime1"] = datetime1
            dataObject["DateTime2"] = datetime2
            dataObject["Last_Delivery_Date"] = lastDeliveryDateTime

            dataObject["Key2"] = symbol
            dataObject["Instrument_Type"] = "Future"
            # dataObject["InstrumentType2"] = "Future"

            # ---Save to Database---
            # database.Upsert("Instruments", "Future", {"Key": symbol}, dataObject)
            documants.append(dataObject)
            #
            # futuresInTrading.append(symbol)

    return documants


# ---更新期货合约列表---
# 1000010084000000 全部中国商品 （品种代码，非合约代码）
# 1000016345000000 全球所有期货合约 （15300种 2021-6-3）
# 1000028001000000 国内期货合约，含到期 (6900合约)
# 1000015512000000 国内期货合约（661种 2021-6-3）
def Download_Future_List(database, realtime=None, datetime1=None, cold_start=False):

    if datetime1 == None:
        datetime1 = datetime.datetime.now()

    # ---Load Database---
    instruments_in_database = {}
    instruments = database.Find("financial_data", "instrument_future")
    for instrument in instruments:
        symbol = instrument.get("symbol")
        if not symbol:
            symbol = instrument("Symbol")
        instruments_in_database[symbol] = instrument

    # ---Request Trading List---
    # list1, dt = Wind.WSet_Instruments(datetime1, sectorName="中金所全部品种")
    # list2, dt = Wind.WSet_Instruments(datetime1, sectorName="上期所全部品种")
    # list3, dt = Wind.WSet_Instruments(datetime1, sectorName="大商所全部品种")
    # list4, dt = Wind.WSet_Instruments(datetime1, sectorName="郑商所全部品种")

    # list = []
    # list.extend(list1)
    # list.extend(list2)
    # list.extend(list3)
    # list.extend(list4)

    # ---2021-6-3 修改为更简单的方法，一次索取所有交易所数据---
    list = Wind.WSet_Instruments(datetime1, sectorName="1000028001000000")  # 用的全部合约，避免遗漏数据


    #
    if list == None or len(list) == 0:
        print("No Data, Can't Update Future_List")
        return

    # ---if New listed? ---
    futures_in_trading = []
    newSymbols = []
    for d in list:
        symbol = d["Symbol"]
        existed = instruments_in_database.get(symbol)
        if existed != None:
            futures_in_trading.append(symbol)
        else:
            newSymbols.append(symbol)
            print("New Contract", symbol)

    #
    print("Total Listed Futures @" + str(datetime1) + " # " + str(len(list)) + ", New Contract # " + str(len(newSymbols)))
    documents = Download_Future_Contract_Info(newSymbols)
    database.Upsert_Many("financial_data", "instrument_future", {}, documents)

    # ---return date not None---
    print("Finish to Update Futures Contracts", datetime.datetime.now())

    # if realtime != None:
    #     realtime.Set("FuturesInTrading", futuresInTrading)

    # ---自动检测新品种，并形成指数---
    Update_Future_Index(database)

    #
    if cold_start:
        Download_Total_Future_Contract(database, datetime1=None, datetime2=datetime1)


def Download_Total_Future_Contract(database, datetime1=None, datetime2=None):
    #
    if datetime1 == None:
        datetime1 = datetime.datetime(1990,1,1)
    #
    df_future_index = database.Get_Instruments_DataFrame(instrument_type="futureindex")
    product_list = df_future_index["symbol"].to_list()
    #
    count = 0
    for symbol in product_list:
        count += 1
        if count <= 1:
            continue
        print("Process Product",count, symbol)

        # w.wset("futurecc","startdate=2018-01-01;enddate=2020-09-03;wind_code=IF.CFE")
        params = {}
        params["startdate"] = datetime1.strftime('%Y-%m-%d')
        params["enddate"] = datetime2.strftime('%Y-%m-%d')
        params["wind_code"] = symbol
        #
        data = Wind.WSET("futurecc", params)
        if data == None:
            print("No Data", symbol)
            continue

        symbol_list = []
        for one_data in data:
            symbol_list.append(one_data["wind_code"])
        #
        documents = Download_Future_Contract_Info(symbol_list)
        database.Upsert_Many("Instruments", "Future", {}, documents)
        a = 0


# ---发现新期货品种---
def Update_Future_Index(database):
    #
    index_symbol_list = []
    index_in_database = database.Find("financial_data", "instrument_futureindex")

    for index in index_in_database:
        symbol = index.get("symbol")
        if not symbol:
            symbol = index("Symbol")
        index_symbol_list.append(symbol)

    #
    instruments_in_database = database.Find("financial_data", "instrument_futureindex")

    infos = {}
    symbols_to_update = []
    for instrument in instruments_in_database:
        symbol = instrument["raw_code"] + "." + instrument["exchange_code"]
        #---
        if symbol not in index_symbol_list and symbol not in symbols_to_update:
            print("Found new Instrument " + symbol)
            symbols_to_update.append(symbol)
            infos[symbol] = instrument

    if len(symbols_to_update) == 0:
        print("No new Future Instrument")
        return

    print(str(len(symbols_to_update)) + " New Future Instrument to update")
    print(symbols_to_update)
    #
    fields = ["sec_name", "exch_eng"]
    fields.append("cdmonths")  # 合约月份说明
    fields.append("thours")  # 最新交易时间说明
    fields.append("ltdated")  # 最后交易日说明
    fields.append("ddate")  # 交割日期说明
    fields.append("ftmargins")  # 最初交易保证金
    fields.append("contract_issuedate")  # 标准合约上市日
    #
    data = Wind.WSS(symbols_to_update, fields)

    #
    documents = []
    for iSymbol in range(len(symbols_to_update)):
        symbol = symbols_to_update[iSymbol]
        dataObject = {}
        dataObject["Symbol"] = symbol
        dataObject["Description"] = data[iSymbol]["sec_name"]
        dataObject["Exchange"] = data[iSymbol]["exch_eng"]
        dataObject["Listed_Contracts"] = data[iSymbol]["cdmonths"]
        dataObject["Trading_Hours"] = data[iSymbol]["thours"]
        dataObject["Termination_Of_Trading"] = data[iSymbol]["ltdated"]
        dataObject["Delivery_Date"] = data[iSymbol]["ddate"]
        dataObject["Minimum_Margin"] = data[iSymbol]["ftmargins"]
        #
        dataObject["Change_Limit"] = infos[symbol]["change_limit"]
        dataObject["Minimum_Move"] = infos[symbol]["minimum_move"]
        dataObject["Unit"] = infos[symbol]["unit"]
        dataObject["Quotation"] = infos[symbol]["quotation"]
        dataObject["Raw_Code"] = infos[symbol]["raw_code"]
        dataObject["Exchange_Code"] = infos[symbol]["exchange_code"]
        #
        issueDate = Gadget.FilterWindDateTimeDirty(data[iSymbol]["contract_issuedate"])
        if issueDate < datetime.datetime(1900,1,1):
            dataObject["DateTime1"] = issueDate
        else:
            # dataObject["DateTime1"] = Gadget.ToUTCDateTime(issueDate)
            dataObject["DateTime1"] = issueDate


        maxDateTime = datetime.datetime(2100, 1, 1)
        # dataObject["DateTime2"] = Gadget.ToUTCDateTime(maxDateTime)
        dataObject["DateTime2"] = maxDateTime

        #
        # dataObject["Key2"] = symbol
        # dataObject["IsIndex"] = True
        dataObject["Instrument_Type"] = "FutureIndex"
        # dataObject["InstrumentType2"] = "FutureIndex"
        # database.Upsert("Instruments", "Future", {"Key": symbol}, dataObject)
        documents.append(dataObject)
    #
    database.Upsert_Many("financial_data", "instrument_futureindex", {}, documents)


def Download_DailyBar_20200903(database):
    raw_codes = ["T", "TF", "TS","TT","TL"]
    # raw_codes = ["IF", "IC", "IH"]
    for raw_code in raw_codes:
        df_instruments = database.GetDataFrame("financial_data", "instrument_future", filter=[("raw_code", raw_code)], sort=[])
        for index, entry in df_instruments.iterrows():
            symbol = entry["symbol"]
            datetime1 = entry["datetime1"]
            datetime2 = entry["datetime2"]
            #
            DataProcess.Download_DailyBars(database, symbol, "Future", datetime1, datetime2)
            a = 0


if __name__ == '__main__':
    #
    pathfilename = os.getcwd() + "\..\Config\config2.json"
    config = Config.Config(pathfilename)
    database = config.DataBase("JDMySQL")
    realtime = config.RealTime()

    Wind.w.start()
    # Download_Future_List(database, realtime)
    # Download_Total_Future_Contract(database, datetime2=datetime.datetime(2020, 9, 1))

    Download_DailyBar_20200903(database)

    datetime2 = datetime.datetime(2020, 8, 21)
    DataProcess.Automatic_Download_DailyQuote(database, datetime2, instrumentType="Future", startIndex=0,
                                              config=config)
